-- Version: v1.1
-- Last modified: 2010-05-19T06:33:14Z
-- Last modified by: joselucas

local function print(value)
	if DEFAULT_CHAT_FRAME then
		DEFAULT_CHAT_FRAME:AddMessage(value);
	end

	if SELECTED_CHAT_FRAME and SELECTED_CHAT_FRAME ~= DEFAULT_CHAT_FRAME then
		SELECTED_CHAT_FRAME:AddMessage(value);
	end
end;

local function printf(stringFormat, ...)
	local msg = string.format(stringFormat, ...);
	print(msg);
end;

local function createHyperlink(type, data, text)
	return string.format("|H%s:%s|h%s|h", type, data, text);
end

local function dec2hex(dec)
	return string.format("%x", dec);
end

local function hex2dec(hex)
	return tonumber(hex, 16)
end

local function SolPercentToHex(percent)
	if (percent >= 255) then return "FF"; end
	if (percent == 0) then return "00";	end
	local c1 = dec2hex(math.floor(percent / 16));
	local c2 = dec2hex(math.floor(percent % 16));
	if (c1 == "") then c1 = "0"; end
	return c1 .. c2;
end

local function split(str, delim)
    if not delim then
        delim = " ";
    end

    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str };
    end

    local result = {};
    local pat = "(.-)" .. delim .. "()";
    local nb = 0;
    local lastPos;
	
    for part, pos in string.gfind(str, pat) do
        nb = nb + 1;
        result[nb] = part;
        lastPos = pos;
    end
	
    -- Handle the last field
    result[nb + 1] = string.sub(str, lastPos);
    return result;
end

------------------

local me = {
	name = "MonsterCardTooltip",
	version = "v1.1",
	author = "Aulid@Osha",
	description = "", -- localized
	enabled = true,
	debug = false,
	locale = nil, -- translations
	cardCategories = 16,
	cardList = nil,
};

function me.OnLoad(this)
	this:RegisterEvent("VARIABLES_LOADED");
	this:RegisterEvent("CARDBOOKFRAME_UPDATE");

	-- load default locale if needed
	if me.locale == nil then
		local filename = string.format("Interface\\Addons\\%s\\locales\\locale.enus.lua", me.name);
		dofile(filename);
	end

	-- set slash commands
	SLASH_MonsterCardTooltip1 = "/card";
	SlashCmdList["MonsterCardTooltip"] = me.SlashCommand;

	SLASH_MonsterCardTooltipRemove1 = "/removecard";
	SlashCmdList["MonsterCardTooltipRemove"] = me.RemoveCard;
end

function me.OnEvent(this, event, arg1, arg2)
	if event == "VARIABLES_LOADED" then
		me.description = me.locale.AddOnDescription;
		me.CreateCardList();
		me.HookFunctions();
	elseif me.enabled and event == "CARDBOOKFRAME_UPDATE" then
		me.CreateCardList();
	end
end

function me.CreateCardList()
	if me.cardList == nil then
		me.cardList = {};
	end

	for x = 0, me.cardCategories do
		local cardCount = LuaFunc_GetCardMaxCount(x);
		local categoryName = LuaFunc_GetString("SYS_RACE_" .. x);

		if cardCount ~= nil and cardCount > 0 then
			for y = 1, cardCount do
				local id, flag, name, tip, race, rare, resist, sp = LuaFunc_GetCardInfo(x, y - 1);
				local color;

				if name == nil or name == "" or string.sub(name, 1, 1) == "?" then
					name, color = me.GetCardName(id);
				end

				if name ~= "" then
					me.cardList[id] = {
						flag = flag,
						name = name,
						color = color,
						tip = tip,
						category = categoryName,
						race = race,
						rare = rare,
						resist = resist,
						sp = sp,
						Contains = me.CardContains,
					};
				end
			end
		end
	end
end

function me.GetCardName(cardID)
	local cardIDHex = dec2hex(cardID);
	local link = createHyperlink("item", cardIDHex, "[Card]");

	MonsterCardTooltipTooltip:SetText("")
	MonsterCardTooltipTooltip:SetHyperLink(link)
	local r, g, b = MonsterCardTooltipTooltipTextLeft1:GetColor();
	local color = SolPercentToHex(r * 256) .. SolPercentToHex(g * 256) .. SolPercentToHex(b * 256);
	local name = MonsterCardTooltipTooltipTextLeft1:GetText()
	MonsterCardTooltipTooltip:Hide();

	name = string.match(name, ".+ %- (.+)");
	return name, color;
end

function me.CheckCardTooltip(tooltip, link)
	if not me.enabled or link == nil or IsAltKeyDown() then
		return;
	end

	local cardID, card;

	if link then
		local linkType, linkData, linkText = ParseHyperlink(link);

		if linkData then
			local cardIDHex = string.match(linkData, "(%x+)");

			if cardIDHex then
				cardID = hex2dec(cardIDHex);
				card = me.cardList[cardID];
			end
		end
	end

	if cardID == nil or card == nil then
		return;
	elseif card.color == nil then
		local name, color = me.GetCardName(cardID);
		card.color = color;
	end

	-- id, flag, name, color, tip, category, race, rare, resist, sp
	tooltip:ClearLines();
	tooltip:SetText(string.format("|cff%s%s - %s|r", card.color, me.locale.Card, card.name));
	tooltip:AddLine(card.tip);

	if card.flag == 0 then
		tooltip:AddLine(string.format("|cffff0000%s|r", me.locale.NotLearned));
	else
		tooltip:AddLine(string.format("|cff00ff00%s|r", me.locale.Learned));
	end

	tooltip:AddLine(string.format("%s: |cffffff00%s|r", me.locale.Category, card.category));

	local location;
	local zoneID = me.mobData[cardID];

	if zoneID then
		location = GetZoneLocalName(zoneID);
	else
		location = me.locale.UnknownLocation;
	end

	tooltip:AddLine(string.format("%s: |cffffff00%s|r", me.locale.Location, location));
	tooltip:AddLine(string.format("%s: |cffffff00%s|r", me.locale.Stats, card.sp));
end

function me.Enable()
	me.enabled = true;
	me.CreateCardList();
end

function me.Disable()
	me.enabled = false;
	me.cardList = nil;
end

function me.RegisterAddOnManager()
	if AddonManager then
		local addon = {
			name = me.name,
			version = me.version,
			author = me.author,
			description = me.description,
			icon = nil,
			category = nil,
			configFrame = nil,
			slashCommand = "/card",
			miniButton = nil,
			disableScript = me.Disable(),
			enableScript = me.Enable(),
		};

		if AddonManager.RegisterAddonTable then
			AddonManager.RegisterAddonTable(addon);
		else
			AddonManager.RegisterAddon(addon.name, addon.description, addon.icon, addon.category, addon.configFrame, addon.slashCommand, addon.miniButton, addon.version, addon.author);
		end;
	else
		printf(me.locale.AddOnLoaded, me.name, me.version);
	end
end

function me.SlashCommand(frame, txt)
	if txt == nil then
		txt = "";
	else
		txt = string.lower(txt);
	end

	if txt == "" then
		-- toggle
		if me.enabled then
			me.Enable();
			printf(me.locale.AddOnDisabled, me.name);
		else
			me.Disable();
			printf(me.locale.AddOnEnabled, me.name);
		end
	elseif txt == "on" or txt == "enable" then
		me.Enable();
		printf(me.locale.AddOnEnabled, me.name);
	elseif txt == "off" or txt == "disable" then
		me.Disable();
		printf(me.locale.AddOnDisabled, me.name);
	elseif txt == "reset" then
		me.CreateCardList();
	else
		me.SearchCards(txt);
	end
end

function me.CardContains(card, text)
	if text == nil or text == "" then
		return false;
	else
		text = string.lower(text);
	end
	
	-- id, flag, name, color?, tip, category, race, rare, resist, sp
	
	if (text == "learned" and card.flag == 1) or (text == "!learned" and card.flag == 0) then
		return true;
	elseif string.match(string.lower(card.name), text) then
		return true;
	elseif string.match(string.lower(card.category), text) then
		return true;
	elseif string.match(string.lower(card.sp), text) then
		return true;
	end
	
	return false;
end

function me.SearchCards(txt)
	local words = split(txt, ",");
	
	if me.cardList == nil then
		me.CreateCardList();
	end

	-- id, flag, name, color?, tip, category, race, rare, resist, sp
	for id, card in pairs(me.cardList) do
		local isMatch = true;

		for _, word in ipairs(words) do
			isMatch = isMatch and card:Contains(word);
		end

		if isMatch then
			if card.color == nil then
				local name, color = me.GetCardName(id);
				card.color = color;
			end

			local cardIDHex = dec2hex(id);
			local linkText = string.format("|cff%s[%s - %s]|r", card.color, me.locale.Card, card.name);
			local link = createHyperlink("item", cardIDHex, linkText);
			print(link);
		end
	end
end

function me.RemoveCard(frame, txt)
	if txt == nil or txt == "" then
		print("Usage: /removecard [CardLink]");
		return;
	end

	local linkType, linkData, linkText = ParseHyperlink(txt);
	local card, cardID;
	
	if linkData then
		local cardIDHex = string.match(linkData, "(%x+)");

		if cardIDHex then
			cardID = hex2dec(cardIDHex);
			card = me.cardList[cardID];
		end
	end
	
	if card == nil then
		print("Link is not a valid monster card link.");
	elseif card.flag == 0 then
		print("You do not have this card.");
	else
		LuaFunc_TakeOutCard(cardID);
	end
end

function me.HookFunctions()
	local GameTooltip_obj = _G.GameTooltip;
	local GameTooltipHyperLink_obj = _G.GameTooltipHyperLink;

	local SetAuctionBrowseItem_orig = GameTooltip_obj["SetAuctionBrowseItem"];
	function GameTooltip:SetAuctionBrowseItem(id)
		SetAuctionBrowseItem_orig(GameTooltip_obj, id);
		me.CheckCardTooltip(self, GetAuctionBrowseItemLink(id));
	end

	local SetBagItem_orig = GameTooltip_obj["SetBagItem"];
	function GameTooltip:SetBagItem(id)
		SetBagItem_orig (GameTooltip_obj, id);
		me.CheckCardTooltip(self, GetBagItemLink(id));
	end

	local SetBankItem_orig = GameTooltip_obj["SetBankItem"];
	function GameTooltip:SetBankItem(id)
		SetBankItem_orig(GameTooltip_obj, id);
		me.CheckCardTooltip(self, GetBankItemLink(id));
	end

	local SetBootyItem_orig = GameTooltip_obj['SetBootyItem'];
	function GameTooltip:SetBootyItem(id)
		SetBootyItem_orig(GameTooltip_obj, id);
		me.CheckCardTooltip(self, GetBootyItemLink(id));
	end

	-- Inventory Viewer 1.4+
	-- thx to: Zilvermoon
	if (GameTooltip_obj["SetHouseItem"]) then
		local SetHouseItem_orig = GameTooltip_obj["SetHouseItem"];
		function GameTooltip:SetHouseItem(ParentDBID,ButtonId)
			SetHouseItem_orig(GameTooltip_obj,ParentDBID,ButtonId);
			me.CheckCardTooltip(self, Houses_GetItemLink(ParentDBID,ButtonId));
		end

		local SetStoreItem_orig = GameTooltip_obj["SetStoreItem"];
		function GameTooltip:SetStoreItem(tab,ButtonId)
			SetStoreItem_orig(GameTooltip_obj,tab,ButtonId);
			if (tab == "SELL") then
				me.CheckCardTooltip(self,GetStoreSellItemLink(ButtonId));
			elseif (tab == "BUYBACK") then
				me.CheckCardTooltip(self,GetStoreBuyBackItemLink(ButtonId));
			end
		end

		local IVSetHyperLink_orig = GameTooltip_obj["SetHyperLink"];
		function GameTooltip:SetHyperLink(link)
			IVSetHyperLink_orig(GameTooltip_obj, link);
			me.CheckCardTooltip(self, link);
		end
	end

	local SetHyperLink_orig = GameTooltipHyperLink_obj["SetHyperLink"];
	function GameTooltipHyperLink:SetHyperLink(link)
		SetHyperLink_orig(GameTooltipHyperLink_obj, link);
		me.CheckCardTooltip(self, link);
	end

	-- Advanced Auctionhouse 1.2+
	-- thx to: Graves
	if(AA_Tooltip) then
		local AA_Tooltip_obj = AA_Tooltip;
		local SetHyperLink_orig = AA_Tooltip_obj["SetHyperLink"];
		function AA_Tooltip:SetHyperLink(link)
			SetHyperLink_orig(AA_Tooltip_obj, link);
			me.CheckCardTooltip(self, link);
		end
	end
end

_G[me.name] = me;


